using System;
using System.Data;
using System.EnterpriseServices;
using System.Reflection;
using System.Threading;
//using IBatisNet.Common.Transaction;
//using IBatisNet.DataMapper;
using log4net;
using NHibernate;
using NHibernate.Transaction;
using Sedna.Core.Persistence.Hql;

namespace Sedna.Core.Persistence
{
	/// <summary>
	/// an implementation of the interface that holds a current transaction
	/// in a current thread DataSlot (the name of the slot is 'Sedna.NHibernateTx')
	/// </summary>
	public class CurrentThreadTxManager : ITxManager
	{
        private ILog log = LogManager.GetLogger(typeof(CurrentThreadTxManager));

	    public bool BeginOrJoinTx()
		{
            NHibernate.ITransaction tx = GetCurentTx(); 
	        if (tx != null && tx.IsActive)
			{
                log.Debug("Joining to existing distributed transaction");
                return false;//joining the existing tx
			}
			CreateNewTx();
			return true;
		}

		public void CommitTx()
		{
            ISession currentSession = NHibernateHelper.GetCurrentSession();
            currentSession.Transaction.Commit();
            log.Debug("Database transaction committed.");
		}

		public void CommitTx(bool isMyTx)
		{
			if(isMyTx)
			{
				CommitTx();
			}
		}

		public void RollbackTx()
		{
            ISession currentSession = NHibernateHelper.GetCurrentSession();//sessionFactory.GetSession();
				currentSession.Transaction.Commit();
                log.Debug("Database transaction rollbacked. ");
		}

		public NHibernate.ITransaction CurrentTx
		{
			get
			{
				return GetCurentTx();
			}
		}

		private void CreateNewTx()
		{
		    log.Debug("Creating new database transaction");
            ISession currentSession = NHibernateHelper.GetCurrentSession();
		    currentSession.BeginTransaction();
		}


        private NHibernate.ITransaction GetCurentTx()
		{
            if (!NHibernateHelper.GetCurrentSession().IsOpen)
                throw new PstStateException("attempt to create a transaction when session is not started");
            
            return NHibernateHelper.GetCurrentSession().Transaction;
		}

	}
}
